﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using Intorise.Common;

namespace Model
{
    public class Thing
    {
        static Dictionary<string, Thing> dict = new Dictionary<string, Thing>();
        static Dictionary<string, uint> items = new Dictionary<string, uint>();

        /// <summary>
        /// 物体编号
        /// </summary>
        public uint ID { get; set; }
        /// <summary>
        /// 物体实例编号
        /// </summary>
        public long InstanceID { get; set; }
        public string Name { get; set; }
        public DateTime CreateDate { get; set; }
        /// <summary>
        /// 物品数量
        /// </summary>
        public int Count { get; set; }
        /// <summary>
        /// 物品版本号
        /// </summary>
        public byte[] Version { get; set; }

        /// <summary>
        /// 是否卓越物品
        /// </summary>
        public bool IsEximious { get; set; }

        /// <summary>
        /// 是否装备
        /// </summary>
        public bool IsEquipment { get; set; }

        public Thing()
        {
            CreateDate = DateTime.Now;
        }

        public enum MedicinalType
        {
            HP0 = 1,
            HP1 = 3,
            HP2 = 5,
            MP0 = 2,
            MP1 = 4,
            MP2 = 6
        }

        static Thing()
        {
            dict.Add("小型生命药包", new Medicinal { Type = 0, Name = "小型生命药包", AddHP = 2000, Gold = new byte[] { 0x02, 0xC4 }, CD = 5, ID = 0x9A0CC801 });
            dict.Add("小型魔法药包", new Medicinal { Type = 0, Name = "小型魔法药包", AddHP = 2000, Gold = new byte[] { 0x02, 0xC6 }, CD = 5, ID = 0x000186B4 });
            dict.Add("大型生命药包", new Medicinal { Type = 0, Name = "大型生命药包", AddHP = 2000, Gold = new byte[] { 0x02, 0xC6 }, CD = 5, ID = 0x000186B7 });
            dict.Add("大型魔法药包", new Medicinal { Type = 0, Name = "大型魔法药包", AddHP = 2000, Gold = new byte[] { 0x02, 0xC6 }, CD = 5, ID = 0x000186B8 });
            //dict.Add("小型治疗药水", new Medicinal { Type = 0x02, Type0 = 0x01, Name = "小型治疗药水", AddHP = 800, Gold = new byte[] { 0x02, 0xC4 }, CD = 5, ID = 0x9A0CC8, Type1 = new byte[] { 0x9A, 0x0C, 0xC8 } });
            //dict.Add("中型治疗药水", new Medicinal { Type = 06, Name = "中型治疗药水", AddHP = 2000, Gold = new byte[] { 0x02, 0xC6 }, CD = 5, ID = 0x9A0C9003 });
            //dict.Add("大型治疗药水", new Medicinal { Type = 0x0A, Name = "大型治疗药水", AddHP = 8000, Gold = new byte[] { 0x02, 0xC8 }, CD = 5, ID = 0x9A0CE807 });
            //dict.Add("小型魔力药水", new Medicinal { Type = 4, Name = "小型魔力药水", AddMP = 0.2, Gold = new byte[] { 0x02, 0xCA }, CD = 3, ID = 0x9A0CD804 });
            //dict.Add("中型魔力药水", new Medicinal { Type = 8, Name = "中型魔力药水", AddMP = 0.3, Gold = new byte[] { 0x02, 0xCC }, CD = 3, ID = 0x9A0CB009 });
            //dict.Add("大型魔力药水", new Medicinal { Type = 0x0C, Name = "大型魔力药水", AddMP = 0.4, Gold = new byte[] { 0x02, 0xCE }, CD = 3, ID = 0x9A0CB817 });
            dict.Add("金币", new Item { Name = "金币", ID = 0x0086ba55 });
            dict.Add("金币0", new Item { Name = "金币0", ID = 0x0088ba55 });
            dict.Add("百万金币", new Item { Name = "百万金币", ID = 0x00DEBA55 });
            dict.Add("传送券", new Item { Name = "传送券", ID = 0x00E4B518 });
            dict.Add("2倍经验", new Item { Name = "2倍经验", ID = 0xC0B618 });
            dict.Add("2倍经验1", new Item { Name = "2倍经验1", ID = 0xE0B518 });
            dict.Add("玛雅礼包", new Item { Name = "玛雅礼包", ID = 0x00D09459 });
            dict.Add("恶魔", new Item { Name = "恶魔", ID = 0xD0843D });
            //dict.Add("翅膀", new Item { Name = "翅膀", ID = 0xD4BA55 });
            //dict.Add("等级礼包", new Item { Name = "等级礼包", ID = 0xD88E59 });

            dict.Add("35级等级礼包", new Item { Name = "35级等级礼包", ID = 0x00D28E59 });  //35级
            dict.Add("会员", new Item { Name = "会员", ID = 0xCABA55 });    //会员
            dict.Add("46级等级礼包", new Item { Name = "46级等级礼包", ID = 0xD48E59 });//46级
            dict.Add("攻速卷", new Item { Name = "攻速卷", ID = 0x8C9B0C });    //攻速卷
            dict.Add("56级等级礼包", new Item { Name = "56级等级礼包", ID = 0xD68E59 });//56级
            dict.Add("祝福宝石", new Item { Name = "祝福宝石", ID = 0x829F49 });
            dict.Add("灵魂宝石", new Item { Name = "灵魂宝石", ID = 0x849F49 });
            dict.Add("玛雅之石", new Item { Name = "玛雅之石", ID = 0x869F49 });
            dict.Add("生命宝石", new Item { Name = "生命宝石", ID = 0x889F49 });
            dict.Add("魔魂之翼", new Item { Name = "魔魂之翼", ID = 0x0007A191 });
            dict.Add("千万金币", new Item { Name = "千万金币", ID = 0xDABC55 });

            dict.Add("登陆1", new Item { Name = "登陆1", ID = 0x00809B0C }); //生命卷轴
            dict.Add("登陆2", new Item { Name = "登陆2", ID = 0x00C69B0C }); //精魄
            dict.Add("登陆3", new Item { Name = "登陆3", ID = 0x00E2B518 }); //2.5倍
            dict.Add("寻宝券", new Item { Name = "寻宝券", ID = 0x00FEBA55 }); //寻宝券


            dict.Add("贵礼包", new Item { Name = "贵礼包", ID = 0x00FCB25A }); //贵宾礼包
            dict.Add("贵称号", new Item { Name = "贵称号", ID = 0x0090BF55 }); //贵宾称号

            dict.Add("第一天礼包", new Item { Name = "第一天礼包", ID = 0x00EEB25A }); //第一天礼包
            dict.Add("子鼠服称号", new Item { Name = "子鼠服称号", ID = 0X00C8CC55 }); //第一天礼包
            dict.Add("丑牛服称号", new Item { Name = "丑牛服称号", ID = 0X00CACC55 });
            dict.Add("寅虎服称号", new Item { Name = "寅虎服称号", ID = 0X00CCCC55 });
            dict.Add("卯兔服称号", new Item { Name = "卯兔服称号", ID = 0X00CECC55 });
            dict.Add("辰龙服称号", new Item { Name = "辰龙服称号", ID = 0X00D0CC55 });
            dict.Add("巳蛇服称号", new Item { Name = "巳蛇服称号", ID = 0X00D2CC55 });
            dict.Add("午马服称号", new Item { Name = "午马服称号", ID = 0X00D4CC55 });
            dict.Add("未羊服称号", new Item { Name = "未羊服称号", ID = 0X00D6CC55 });
            dict.Add("申猴服称号", new Item { Name = "申猴服称号", ID = 0X00D8CC55 });
            dict.Add("酉鸡服称号", new Item { Name = "酉鸡服称号", ID = 0X00DACC55 });
            dict.Add("戌狗服称号", new Item { Name = "戌狗服称号", ID = 0X00DCCC55 });
            dict.Add("亥猪服称号", new Item { Name = "亥猪服称号", ID = 0X00EECC55 });

            dict.Add("熊猫", new Item { Name = "熊猫", ID = 0x0007A191 });

            dict.Add("兑_外", new Item { Name = "兑_外", ID = 0x82B918 });
            dict.Add("兑_域", new Item { Name = "兑_域", ID = 0x84B918 });
            dict.Add("兑_争", new Item { Name = "兑_争", ID = 0x86B918 });
            dict.Add("兑_霸", new Item { Name = "兑_霸", ID = 0x88B918 });

            dict.Add("初级坐骑丹", new Item { Name = "坐骑丹", ID = 0xE09A0C });

            dict.Add("小型治疗药水", new Medicinal { ID = 0xC49A0C, Name = "小型治疗药水", Type = 1, CD = 5, AddHP = 800, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x02, 0x02, 0x02, 0xC4, 0x9A, 0x0C, 0xC8, 0x01, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });
            dict.Add("中型治疗药水", new Medicinal { ID = 0xC69A0C, Name = "中型治疗药水", Type = 3, CD = 5, AddHP = 800, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x06, 0x02, 0x02, 0xC6, 0x9A, 0x0C, 0x90, 0x03, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });
            dict.Add("大型治疗药水", new Medicinal { ID = 0xC89A0C, Name = "大型治疗药水", Type = 4, CD = 5, AddHP = 800, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x0A, 0x02, 0x02, 0xC8, 0x9A, 0x0C, 0xE8, 0x07, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });
            dict.Add("小型魔力药水", new Medicinal { ID = 0xCA9A0C, Name = "小型魔力药水", Type = 2, CD = 3, AddMP = 0.2, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x04, 0x02, 0x02, 0xCA, 0x9A, 0x0C, 0xD8, 0x04, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });
            dict.Add("中型魔力药水", new Medicinal { ID = 0xCC9A0C, Name = "中型魔力药水", Type = 4, CD = 3, AddMP = 0.3, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x08, 0x02, 0x02, 0xCC, 0x9A, 0x0C, 0xB0, 0x09, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });
            dict.Add("大型魔力药水", new Medicinal { ID = 0xCE9A0C, Name = "大型魔力药水", Type = 6, CD = 3, AddMP = 0.4, Data = new byte[] { 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0x9A, 0xF1, 0xA0, 0x9C, 0x01, 0x0C, 0x02, 0x02, 0xCE, 0x9A, 0x0C, 0xB8, 0x17, 0x0A, 0x14, 0x90, 0x4E, 0xD8, 0x04, 0xB0, 0x09, 0x02, 0x06 } });


            dict.Add("坐骑优惠礼包", new Item { Name = "坐骑优惠礼包", ID = 0x00fcbb55 });
            dict.Add("绑钻", new Item { Name = "绑钻", ID = 0x00e6ba55 });
            dict.Add("钨铜", new Item { Name = "钨铜", ID = 0x0088f257 });
            dict.Add("魔法师任务翅膀", new Item { Name = "魔法师任务翅膀", ID = 0x00d4843d });
            dict.Add("珍品.精魄", new Item { Name = "珍品.精魄", ID = 0x0076c69b });

            dict.Add("375礼盒", new Item { Name = "375礼盒", ID = 0x00D8A259 });
            dict.Add("325礼盒", new Item { Name = "325礼盒", ID = 0x00D6A259 });
            dict.Add("275礼盒", new Item { Name = "275礼盒", ID = 0x00D4A259 });
            dict.Add("225礼盒", new Item { Name = "225礼盒", ID = 0x00D2A259 });
            dict.Add("175礼盒", new Item { Name = "175礼盒", ID = 0x00D0A259 });
            dict.Add("125礼盒", new Item { Name = "125礼盒", ID = 0x00CEA259 });
            dict.Add("75礼盒", new Item { Name = "75礼盒", ID = 0x00CCA259 });
            //D0 A2 59
            #region 任务物品
            dict.Add("帝王之书", new Item { Name = "帝王之书", ID = 0xB0BB55 });
            dict.Add("先知之魂", new Item { Name = "先知之魂", ID = 0xB4BB55 });
            dict.Add("精灵之泪", new Item { Name = "精灵之泪", ID = 0xB6BB55 });
            dict.Add("破损的魔导师铠甲", new Item { Name = "破损的魔导师铠甲", ID = 0x00eed556 });//错的
            #endregion

            LoadData();
        }

        public static void LoadData()
        {
            var file = AppDomain.CurrentDomain.BaseDirectory + "items.txt";
            if (!File.Exists(file)) { return; }

            var splitor = new char[] { ' ', '\t' };
            string[] texts = null;
            uint id = 0;

            try
            {
                File.ReadAllLines(file).ToList().ForEach(x =>
                {
                    texts = x.Split(splitor, StringSplitOptions.RemoveEmptyEntries);
                    if (uint.TryParse(texts[0], System.Globalization.NumberStyles.HexNumber, null, out id))
                    {
                        if (!items.ContainsKey(texts[1]))
                        {
                            items.Add(texts[1], id);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                ConsoleBLL.WriteLineError(ex.Message);
            }
        }

        public static void SaveData(Thing thing)
        {
            GameHelper.RunGameThread(() =>
            {
                lock (items)
                {
                    var contents = "\r\n" + thing.ID.ToString("X2") + " " + thing.Name;
                    var file = AppDomain.CurrentDomain.BaseDirectory + "items.txt";
                    File.AppendAllText(file, contents);
                }
                //ConsoleBLL.WriteLine("物品数据已经保存");
            });
        }

        public static Thing GetThing(string name)
        {
            lock (dict)
            {
                var item = dict[name];
                return (Thing)item.MemberwiseClone();
            }
        }

        public static Thing GetThing(uint id)
        {
            lock (dict)
            {
                var item = dict.Where(x => x.Value.ID == id).FirstOrDefault().Value;
                if (item == null) { return null; }
                return (Thing)item.MemberwiseClone();
            }
        }

        public static void RegisterThing(Thing thing)
        {
            lock (dict)
            {
                if (!dict.ContainsKey(thing.Name))
                {
                    dict.Add(thing.Name, thing);
                }
            }

            lock (items)
            {
                if (!items.ContainsKey(thing.Name))
                {
                    items.Add(thing.Name, thing.ID);
                    SaveData(thing);
                }
            }
        }

        public static Medicinal GetThing(MedicinalType type)
        {
            string name = "";
            switch (type)
            {
                case Thing.MedicinalType.HP0:
                    name = "小型治疗药水";
                    break;
                case Thing.MedicinalType.HP1:
                    name = "中型治疗药水";
                    break;
                case Thing.MedicinalType.HP2:
                    name = "大型治疗药水";
                    break;
                case Thing.MedicinalType.MP0:
                    name = "小型魔力药水";
                    break;
                case Thing.MedicinalType.MP1:
                    name = "中型魔力药水";
                    break;
                case Thing.MedicinalType.MP2:
                    name = "大型魔力药水";
                    break;
            }
            var medicinal = (Medicinal)dict[name].MemberwiseClone();
            medicinal.CreateDate = DateTime.Now;
            return medicinal;
        }
    }

    /// <summary>
    /// 怪物
    /// </summary>
    public class Monster : Thing
    {
        public Point Location { get; set; }
        public bool Alive { get; set; }
        public double Distance { get; set; }
        public int AttackedCount { get; set; }

        public Monster()
        {
            Alive = true;
            Name = "未知怪物";
            AttackedCount = 0;
        }
    }

    public abstract class Skill : IAttactDataPack
    {
        public long ID { get; set; }
        public string Name { get; set; }
        /// <summary>
        /// 技能CD
        /// </summary>
        public double CD { get; set; }
        public int MP { get; set; }
        /// <summary>
        /// 目标个数
        /// </summary>
        public int TargetCount { get; set; }
        /// <summary>
        /// 固定CD
        /// </summary>
        public bool IsFixedCD { get; set; }
        public int AttackRange { get; set; }
        public DateTime LastUseTime { get; set; }

        public Skill()
        {
            LastUseTime = DateTime.Now;
            IsFixedCD = false;
        }

        public abstract byte[] GetData(Map map, Player player, Monster monster);

        public abstract byte[] GetData(Map map, Player player, List<Monster> monsters);
    }

    public class Item : Thing
    {

    }

    public class Medicinal : Thing
    {
        public byte Type { get; set; }
        public byte Type0 { get; set; }
        public byte[] Type1 { get; set; }
        public byte[] Gold { get; set; }
        public int AddHP { get; set; }
        public double AddMP { get; set; }
        public double CD { get; set; }
        public byte[] Data { get; set; }
    }
}
